#ifndef __CAN_TASK_H__
#define __CAN_TASK_H__
#include "sys.h"

/*-------------MODBUS 功能码-------------------------------------------------*/
#define FUNC_READ_DO 01      // 读取开关量输出状态寄存器
#define FUNC_READ_DI 02      // 读取开关量输入状态寄存器
#define FUNC_READ_HOLD 03    // 读取保持寄存器
#define FUNC_READ_INPUT 04   // 读取输入寄存器
#define FUNC_SET_DO 05       // 设置开关量输出寄存器
#define FUNC_SET_SINGLE 06   // 写单个寄存器
#define FUNC_SET_MULTIPLE 16 // 写多个寄存器

#define Bat_All_Num 8
#define CanTimeOut 12000 // 1ms*12000=12s

#define CAN_REC_LEN 0xFF
#define CAN_TRN_LEN 0xFF

#define SH_PROTOCOL_READ_FUNC_CODE 0x30  // 读
#define SH_PROTOCOL_WRITE_FUNC_CODE 0x31 // 写

enum SHAREA { SH_DB = 1, SH_IN, SH_OUT, SH_MEM };
enum SH_W_TYPE {
  SH_W_BIT = 1,
  SH_W_BYTE,
  SH_W_WORD,
  SH_W_DWORD,
};
/*--------------接收状态----------------------------------------------------*/
#define ERR_OVER_TIME (-1)

typedef struct {
  uint32_t StdID;
  uint8_t  Buff[256];
  uint8_t  TSH_Buff[256];
  uint8_t  AI_Buff[256];
  uint8_t  DataLen;
  uint8_t  Addr;
  uint8_t  FuncCode;
  uint8_t  State;
  uint8_t  AI_State;
  uint8_t  TSH_State;
  uint16_t OverTimeCount;
  uint8_t  OverTimeFlag;
} CANREC;
extern CANREC CanRec;

typedef struct {
  uint8_t Buff[256];
  uint8_t TxCount;
  uint8_t DataLen;
  uint8_t State;
} CANTRN;

typedef struct {
  uint8_t Buff[256];
  uint8_t DataLen;
} CANUPLODE;

void CAN_Response(void);
void CAN_Module_Data(void);
void CAN_RX_Communication(void);
u8   CanRecCRC(u16 rd, uint8_t usDataLen);
u16  CRC16(u8* _pBuf, uint16_t _usLen);
u16  msrCRC(char* pcMess, u8 wLen);

void Rec_TimeOut_Chk(void);
void CAN_01_Answer(void);
void CAN_02_Answer(void);
void CAN_03_Answer(void);
void CAN_04_Answer(void);
void CAN_05_Answer(void);
void CAN_06_Answer(void);
void CAN_15_Answer(void);
void CAN_16_Answer(void);
void ClearDataBuff(void);
void Can_Uplode(void);
void MODH_SendAckWithCRC(void);
void MODH_Send05H(uint8_t _addr, uint16_t _reg, uint16_t _value); // 控制扩展模块线圈
void MODH_Send06H(uint8_t _value);                                // 修改扩展模块地址
/**********************************************************************************/
#endif
